package core.course;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import core.interfaces.IBooleanOperator;

/**
 * This class describes a course given at the Technion.<br>
 * The class was extended by Adam Levi and Tal Steier
 * 
 * @author omerlevy
 */
public class Course implements IBooleanOperator, Serializable
{

	/* --- Constructors --- */
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 9222788591884748726L;

	/**
	 * Constructor.
	 * @param time The time slot in which the course is given.
	 * @param workload The amount of time and energy needed to pass the course.
	 */
	public Course(int time, int workload) {
		this.time = time;
		this.workload = workload;
		adjacents = new HashSet<Course>();
	}
	
	
	/* --- Public Methods --- */
	
	@Override 
	public String toString()
	{
		return String.format(
				"Course ID: %d\n" +
				"Time: %d, Workload: %d, AvgGrade %d\n" +
				"Adjacents %s", getId(), getTime(), getWorkload(), getGrade(), getAdjacents().toString());
	};

	/**
	 * @return The course's one-to-one identifier.
	 */
	public int getId() {
		return id;
	}
	
	/**
	 * @return The time slot in which the course is given.
	 */
	public int getTime() {
		return time;
	}
	
	/**
	 * @return The set of adjacent courses.
	 */
	public Set<Course> getAdjacentsCourses() {
		return adjacents;
	}
	
	public Set<Integer> getAdjacents(){
		Set<Integer> adjacentsAsInt = new HashSet<Integer>();
		for(Course course : adjacents)
		{
			adjacentsAsInt.add(course.getId());			
		}
		return adjacentsAsInt;
	}
	
	/**
	 * @return The amount of time and energy needed to pass the course.
	 */
	public int getWorkload() {
		return workload;
	}
	
	/**
	 * @return The expected grade in the course.
	 */
	public int getGrade() {
		return grade;
	}

	/**
	 * @param id The course's one-to-one identifier.
	 */
	public void setId(int id) {
		this.id = id;
	}
	
	/**
	 * @param grade The expected grade in the course.
	 */
	public void setGrade(int grade) {
		this.grade = grade;
	}
	
	/**
	 * @param course An adjacent course.
	 */
	public void addAdjacentCourse(Course course) {
		if (! equals(course)) {
			adjacents.add(course);
		}
	}
	
	
	/* --- Comparison Methods --- */
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		return (obj != null && 
				((obj instanceof Course) && 
					(((Course) obj).id == id)));
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return id;
	}
	
	
	/* --- Members --- */
	
	/** The course's one-to-one identifier. */
	private int id;
	
	/** The time slot in which the course is given. */
	private int time;
	
	/** The set of adjacent courses. */
	private HashSet<Course> adjacents;
	
	/** The amount of time and energy needed to pass the course. */
	private int workload;
	
	/** The expected grade in the course. */
	private int grade;


}
